package cachetest

import (
	"fmt"
	"github.com/gogf/gf/container/garray"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gcache"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/gconv"
	"strings"
	"time"
)

var Cachetest = new(cachetestApi)

type cachetestApi struct {
}

func (p *cachetestApi) Test1() {
	// 创建一个缓存对象，
	// 当然也可以便捷地直接使用gcache包方法
	c := gcache.New()

	// 设置缓存，不过期
	c.Set("k1", "v1", 0)

	// 获取缓存
	v, _ := c.Get("k1")
	fmt.Println(v)

	// 获取缓存大小
	n, _ := c.Size()
	fmt.Println(n)

	// 缓存中是否存在指定键名
	b, _ := c.Contains("k1")
	fmt.Println(b)

	// 删除并返回被删除的键值
	fmt.Println(c.Remove("k1"))

	// 关闭缓存对象，让GC回收资源
	c.Close()
}

func (p *cachetestApi) Test2() {
	// 当键名不存在时写入，设置过期时间1000毫秒
	gcache.SetIfNotExist("k1", "v1", 1000*time.Millisecond)

	// 打印当前的键名列表
	keys, _ := gcache.Keys()
	fmt.Println(keys)

	// 打印当前的键值列表
	values, _ := gcache.Values()
	fmt.Println(values)

	// 获取指定键值，如果不存在时写入，并返回键值
	v, _ := gcache.GetOrSet("k2", "v2", 0)
	fmt.Println(v)

	// 打印当前的键值对
	data1, _ := gcache.Data()
	fmt.Println(data1)

	// 等待1秒，以便k1:v1自动过期
	time.Sleep(time.Second)

	// 再次打印当前的键值对，发现k1:v1已经过期，只剩下k2:v2
	data2, _ := gcache.Data()
	fmt.Println(data2)
}
func (p *cachetestApi) Test3(key string) ([]string, error) {
	v, err := gcache.GetOrSetFunc("doc_search_result_"+key, func() (interface{}, error) {
		// 当该key的检索缓存不存在时，执行检索
		array := garray.NewStrArray()
		docPath := g.Cfg().GetString("doc.path")
		paths, err := gcache.GetOrSetFunc("doc_files_recursive", func() (interface{}, error) {
			// 当目录列表不存在时，执行检索
			return gfile.ScanDir(docPath, "*.md", true)
		}, 0)
		if err != nil {
			return nil, err
		}
		// 遍历markdown文件列表，执行字符串搜索
		for _, path := range gconv.Strings(paths) {
			content := gfile.GetContents(path)
			if len(content) > 0 {
				if strings.Index(content, key) != -1 {
					index := gstr.Replace(path, ".md", "")
					index = gstr.Replace(index, docPath, "")
					array.Append(index)
				}
			}
		}
		return array.Slice(), nil
	}, 0)
	if err != nil {
		return nil, err
	}
	return gconv.Strings(v), nil
}

func (p *cachetestApi) Test4() {
	// 设置LRU淘汰数量
	c := gcache.New(2)

	// 添加10个元素，不过期
	for i := 0; i < 10; i++ {
		c.Set(i, i, 0)
	}
	n, _ := c.Size()
	fmt.Println(n)
	keys, _ := c.Keys()
	fmt.Println(keys)

	// 读取键名1，保证该键名是优先保留
	v, _ := c.Get(1)
	fmt.Println(v)

	// 等待一定时间后(默认1秒检查一次)，
	// 元素会被按照从旧到新的顺序进行淘汰
	time.Sleep(2 * time.Second)
	n, _ = c.Size()
	fmt.Println(n)
	keys, _ = c.Keys()
	fmt.Println(keys)
}
